package controller

import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"regexp"
	"strings"

	"github.com/gin-gonic/gin"

	"myproject/model"
	"myproject/schemas"
	"myproject/utils"
)

//总路由分发
func UserRegister(userGrp *gin.RouterGroup) {
	userGrp.Use().POST("/reg", reg)
	userGrp.Use().POST("/sendCode", sendCode)
	//获取地址接口
	userGrp.Use().GET("/get_weibo", get_weibo)
	//回调接口
	userGrp.Use().GET("/weiboCallback", weiboCallback)
	userGrp.Use().POST("/bindMobile", bindMobile)
	userGrp.Use().POST("/upload", upload)
	//上传文件
	userGrp.Use().POST("/fileUpload", fileUpload)
	//获取身份证信息 getCardMes
	userGrp.Use().GET("/getCardMes", getCardMes)

	//开户
	userGrp.Use().POST("/createOpenbank", createOpenbank)

	//ws
	// userGrp.Use().GET("/SocketLink", SocketLink)
	// userGrp.Use().GET("/socketSend", socketSend)
}

type MyError struct {
	Code string
	Mes  string
}

//发送验证码
func sendCode(c *gin.Context) {
	//获取参数，手机号
	mobile := c.PostForm("mobile")
	//验证手机号格式是否合法
	reg := "^1[3-9]{1}\\d{9}$"
	result := regexp.MustCompile(reg)
	flag := result.MatchString(mobile)
	if !flag {
		c.JSON(200, gin.H{
			"code": "10011",
			"mes":  "手机号不正确",
		})
	} else {
		//从redis中根据手机号获取验证码
		r := utils.GetRedis()
		value := r.Get(mobile)
		if value == "" {
			//如果不存在生成随机数
			code := utils.RandInt(10000, 99999)
			//调用发短信接口
			utils.SendSms(mobile, code)
			//存入redis
			r.Setex(mobile, 60, code)
			//返回结果
			c.JSON(200, gin.H{
				"code": "200",
				"mes":  "发送成功",
			})

		} else {
			//如果存在直接返回不能重复发
			c.JSON(200, gin.H{
				"code": "10012",
				"mes":  "不能重复发送",
			})
		}

	}

}

//注册
func reg(c *gin.Context) {
	//获取参数
	mobile := c.PostForm("mobile")
	newcode := c.PostForm("code")
	//验证码验证
	r := utils.GetRedis()
	//获取redis中的验证码
	code := r.Get(mobile)
	if code != newcode {
		c.JSON(200, gin.H{
			"code": "10020",
			"mes":  "验证码不正确",
		})
	} else {
		//加入数据库
		user := &model.User{
			Name:   mobile,
			Mobile: mobile,
		}
		db := model.GetDb()
		db.Create(user)
		//生成token返回
		token, _ := utils.ReleaseToken(user.ID)
		c.JSON(200, gin.H{
			"code":   "200",
			"mes":    "注册成功",
			"userid": user.ID,
			"token":  token,
		})
	}

}

//获取微博连接
func get_weibo(c *gin.Context) {
	//微博唯一标识
	clientid := "3674019597"
	//回调地址
	url := "http://127.0.0.1:8000/user/weiboCallback/"

	returnUrl := "https://api.weibo.com/oauth2/authorize?client_id=" + clientid + "&redirect_uri=" + url + "&response_type=code"
	c.JSON(200, gin.H{
		"code": 200,
		"url":  returnUrl,
	})
}

//微博回调
func weiboCallback(c *gin.Context) {
	//获取code
	// code := c.Query("code")
	//组装数据post请求验证
	// data = {"client_id":'3674019597',"client_secret":"7ae99bc0d54ead29fc8d1b9fabd78587",
	// "grant_type":"authorization_code",
	// 'redirect_uri':'http://127.0.0.1:8000/user/weiboCallback/','code':code}
	// geturl := "https://api.weibo.com/oauth2/access_token"
	// data := url.Values{}
	// data.Add("client_id", "3674019597")
	// data.Add("client_secret", "7ae99bc0d54ead29fc8d1b9fabd78587")
	// data.Add("grant_type", "authorization_code")
	// data.Add("redirect_uri", "http://127.0.0.1:8000/user/weiboCallback/")
	// data.Add("code", code)
	// res, _ := http.PostForm(geturl, data)

	// //成功 uid ,token

	// body, _ := ioutil.ReadAll(res.Body)

	// var v interface{}
	// json.Unmarshal([]byte(string(body)), &v)
	// resultmes := v.(map[string]interface{})
	// actoken, flag := resultmes["access_token"]
	// if flag {
	// 	fmt.Println(actoken)
	// }
	// uid, uflag := resultmes["uid"]
	// if uflag {
	// 	fmt.Println(uid)
	// }
	//通过 uid去三方登录表中查询是否存在
	uid := "1231434"
	actoken := "234234234"

	conn := model.GetDb()
	var sflogin model.SfLogin
	conn.First(&sflogin, "Userid=?", uid)

	//如果存在用userid生成token，redirect到vue页面
	if sflogin.ID != 0 {
		//生成token
		token, _ := utils.ReleaseToken(123)
		c.Redirect(http.StatusMovedPermanently, "http://localhost:8080/#/setToken?token="+token+"&userid=1")
	} else {
		c.Redirect(http.StatusMovedPermanently, "http://localhost:8080/#/bindMobile?token="+actoken+"&uid="+uid)
	}
}

func bindMobile(c *gin.Context) {
	createUser := &schemas.CreateUser{}
	_ = c.Bind(createUser)
	token := createUser.Token
	uid := createUser.Uid
	mobile := createUser.Mobile

	//查询用户表中的此手机号是否存在
	var user model.User
	conn := model.GetDb()
	conn.First(&user, "mobile=?", mobile)
	//已经存在找出Userid,写入三方登录表
	var ctokenuserid uint = 0
	if user.ID != 0 {
		//生成token返回
		ctokenuserid = user.ID
	} else {
		//不存在先写用户表，生成一个userid，再写三方登录表
		createUser := &model.User{
			Mobile: mobile,
		}
		conn.Create(createUser)
		ctokenuserid = createUser.ID
	}
	ctoken, _ := utils.ReleaseToken(ctokenuserid)
	//写入三方登录表
	sflogin := &model.SfLogin{
		Uid:      ctokenuserid,
		Token:    token,
		PlatForm: "weibo",
		Userid:   uid,
	}
	conn.Create(sflogin)
	c.JSON(200, gin.H{
		"code":   200,
		"token":  ctoken,
		"userid": ctokenuserid,
	})
}

//上传图片
func upload(c *gin.Context) {
	f, err := c.FormFile("file")
	if err != nil {
		c.JSON(200, gin.H{
			"code": "10020",
			"mes":  "获取文件失败",
		})
		return
	}
	if err := c.SaveUploadedFile(f, "upload/"+f.Filename); err != nil {
		c.JSON(200, gin.H{
			"code": "10021",
			"mes":  "保存文件失败",
		})
		return
	}
	c.JSON(200, gin.H{
		"code": "200",
		"mes":  "上传成功",
	})

}

// var upgrader = websocket.Upgrader{
// 	// 解决跨域问题
// 	CheckOrigin: func(r *http.Request) bool {
// 		return true
// 	},
// } // use default options

// func cmdWebSocket(c *gin.Context) {
// 	ws, err := upgrader.Upgrade(c.Writer, c.Request, nil)
// 	if err != nil {
// 		fmt.Println("upgrade:", err)
// 		return
// 	}
// 	defer ws.Close()
// 	for {
// 		mt, message, err := ws.ReadMessage()
// 		if err != nil {
// 			fmt.Println("read:", err)
// 			break
// 		}
// 		fmt.Printf("recv: %s", message)
// 		err = ws.WriteMessage(mt, message)
// 		if err != nil {
// 			fmt.Println("write:", err)
// 			break
// 		}
// 	}
// }

func fileUpload(c *gin.Context) {
	//获取文件流
	f, err := c.FormFile("file")
	if err != nil {
		c.JSON(200, gin.H{
			"code": "10020",
			"mes":  "获取文件失败",
		})
		return
	}
	//生成文件
	if err := c.SaveUploadedFile(f, "upload/"+f.Filename); err != nil {
		c.JSON(200, gin.H{
			"code": "10021",
			"mes":  "保存文件失败",
		})
		return
	}
	c.JSON(200, gin.H{
		"code": "200",
		"mes":  "保存成功",
	})
}

//获取token的接口
func getBaiduToken() string {
	var host = "https://aip.baidubce.com/oauth/2.0/token"
	var param = map[string]string{
		"grant_type":    "client_credentials",
		"client_id":     "kmPjGuYOjm9neQBhEX8VO2Wf",
		"client_secret": "uYgrB5Zw2AiRLVxQOv46IcMxnfwjTHRy",
	}

	uri, err := url.Parse(host)
	if err != nil {
		fmt.Println(err)
	}
	query := uri.Query()
	for k, v := range param {
		query.Set(k, v)
	}
	uri.RawQuery = query.Encode()

	response, err := http.Get(uri.String())
	if err != nil {
		fmt.Println(err)
	}
	result, err := ioutil.ReadAll(response.Body)
	if err != nil {
		fmt.Println(err)
	}

	var v interface{}
	//把string转成接口
	json.Unmarshal([]byte(string(result)), &v)
	dictdata := v.(map[string]interface{})
	token := dictdata["access_token"].(string)
	return token
}

//获取文字信息
func getCardMes(c *gin.Context) {
	var host = "https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic"
	var accessToken = getBaiduToken()

	uri, err := url.Parse(host)
	if err != nil {
		fmt.Println(err)
	}
	query := uri.Query()
	query.Set("access_token", accessToken)
	uri.RawQuery = query.Encode()

	filebytes, err := ioutil.ReadFile("upload/2.jpg")
	if err != nil {
		fmt.Println(err)
	}

	image := base64.StdEncoding.EncodeToString(filebytes)
	sendBody := http.Request{}
	sendBody.ParseForm()
	sendBody.Form.Add("image", image)
	sendData := sendBody.Form.Encode()

	client := &http.Client{}
	request, err := http.NewRequest("POST", uri.String(), strings.NewReader(sendData))
	if err != nil {
		fmt.Println(err)
	}
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")

	response, err := client.Do(request)
	defer response.Body.Close()
	result, err := ioutil.ReadAll(response.Body)
	if err != nil {
		fmt.Println(err)
	}
	// fmt.Println(string(result))
	//定义一个接口
	var v interface{}
	//把string转成接口
	json.Unmarshal([]byte(string(result)), &v)
	//
	mesdict := v.(map[string]interface{})
	//{'words_result':[["word":"张三"],["word":"171834795924857"]],'code':200,'time':123}
	wordslist := mesdict["words_result"].([]interface{})
	//
	var cardlist []string
	for _, vv := range wordslist {
		words := vv.(map[string]interface{})
		for _, vmes := range words {
			cardlist = append(cardlist, vmes.(string))
		}
	}

	c.JSON(200, gin.H{
		"code": "200",
		"name": cardlist[0],
		"card": cardlist[1],
	})

}

//开户接口
func createOpenbank(c *gin.Context) {
	//从vue获取到信息，添加到开户表中OpenBank
	id := c.PostForm("id")
	fmt.Println(id)
	r := utils.RedisPool
	// f := r.Setnx("atoio33333")
	// fmt.Println(f)
	// cid, _ := strconv.Atoi(id)
	r.ListAdd("openuser1", id)

	c.JSON(200, gin.H{
		"code": "200",
		"mes":  "已经提交，等待审核",
	})

}

//更新开户状态接口
